package com.zsk.sso.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.zsk.sso.util.MockDbUtil;
import com.zsk.sso.vo.ClientInfoVo;

/**
 * SSO 认证服务
 * 
 * @author keke
 * @date 2020/09/27
 */
@Controller
public class LoginController {

    @RequestMapping("/")
    public String index() {
        return "index";
    }

    @RequestMapping("/login")
    public String login() {
        return "login";
    }

    @RequestMapping("/test")
    public String test() {
        return "test";
    }

    /**
     * 检查sso系统是否已经登录
     * 
     * @param redirectUrl
     * @param session
     * @param model
     * @return
     */
    @RequestMapping("/checkLogin")
    public String checkLogin(String redirectUrl, HttpSession session, Model model, RedirectAttributes redAttr) {
        // 1.判断是否有全局的会话
        String token = (String)session.getAttribute("token");
        System.out.println("sso: jsessionid=" + session.getId() + ",检查是否有token=" + token);
        if (StringUtils.isEmpty(token)) {
            // token为空表示没有全局会话，跳转到统一认证中心的登陆页面.
            model.addAttribute("redirectUrl", redirectUrl);
            return "login";
        } else {
            System.out.println("sso: sso已登录，直接重定向 token=" + token + "," + redirectUrl);
            // 系统已经登录，取出令牌信息,重定向到redirectUrl,把令牌带上 http://127.0.0.1:8088/main?token
            redAttr.addAttribute("token", token);
            return "redirect:" + redirectUrl;
        }
    }

    /**
     * sso登录
     * 
     * @param username
     * @param password
     * @param redirectUrl
     * @param session
     * @param model
     * @param redAttr
     * @return
     */
    @RequestMapping("/userLogin")
    public String login(String username, String password, String redirectUrl, HttpSession session, Model model,
        RedirectAttributes redAttr) {
        System.out.println("sso:" + username + "," + password + "," + redirectUrl);
        if ("admin".equals(username) && "123456".equals(password)) {
            // 账号密码匹配
            // 1.创建令牌信息
            String token = UUID.randomUUID().toString();
            // 2.创建全局的会话,把令牌信息放入会话中.
            session.setAttribute("token", token);
            System.out.println("sso: 登录成功,jsessionid=" + session.getId() + ", token=" + token);
            // 3.需要把令牌信息放到数据库中.
            MockDbUtil.addToken(token);
            // 4.如果不是其他系统请求的登录则跳转到sso认证中心的默认页面
            if (StringUtils.isEmpty(redirectUrl)) {
                model.addAttribute("token", token);
                return "index";
            }
            // 5.重定向到redirectUrl,把令牌信息带上. http://127.0.0.1:8088/main?token=
            redAttr.addAttribute("token", token);
            return "redirect:" + redirectUrl + "";
        }
        // 如果账号密码有误,重新回到登录页面,并且把原来的redirectUrl放入request域中.
        if (!StringUtils.isEmpty(redirectUrl)) {
            model.addAttribute("redirectUrl", redirectUrl);
        }
        return "login";
    }

    /**
     * 校验token是否由统一认证中心产生
     *
     */
    @RequestMapping("/verify")
    @ResponseBody
    public String verifyToken(String token, String clientUrl, String jsessionid) {
        if (MockDbUtil.containsToken(token)) {
            // 把客户端的登出地址记录
            List<ClientInfoVo> clientInfoList = MockDbUtil.DB_CLIENT_INFO.get(token);
            if (clientInfoList == null) {
                clientInfoList = new ArrayList<ClientInfoVo>();
                MockDbUtil.DB_CLIENT_INFO.put(token, clientInfoList);
            }
            ClientInfoVo vo = new ClientInfoVo();
            vo.setClientUrl(clientUrl);
            vo.setJsessionid(jsessionid);
            clientInfoList.add(vo);
            // 说明令牌有效,返回true
            return "true";
        }
        return "false";
    }

    @RequestMapping("/loginOut")
    public String logOut(HttpSession session) {
        // 销毁全局会话
        session.invalidate();
        return "redirect:login";
    }

}
